#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#ifdef WIN32
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#endif
#include <thread>

void thread_task(int s)
{
	int len;
	char buf[BUFSIZ];
	while (1)
	{
		/*接收客户端的数据并将其发送给客户端--recvfrom是无连接的*/
		if ((len = recv(s, buf, BUFSIZ, 0)) < 0)
		{
			perror("recv");
		}
		buf[len] = '\0';
		printf("%s:\n", buf);
	}
}

int main(int argc, char *argv[])
{
	int i;
	int client_sockfd;
	int len;
	int sin_size;
	struct sockaddr_in my_addr;								   // 服务器网络地址结构体
	struct sockaddr_in remote_addr;							   // 服务器端网络地址结构体
	char buf[BUFSIZ];										   // 数据传送的缓冲区

#ifdef WIN32															   // 开启网络库
	WORD wVersionRequird = MAKEWORD(2, 2);	// MAKEWORD(主版本,副版本)
	WSADATA wdScokMsg;
	switch (WSAStartup(wVersionRequird, &wdScokMsg))
	{
	case WSASYSNOTREADY:
		printf("重启电脑试试，或者检查网络库\n");
		return -1;

	case WSAVERNOTSUPPORTED:
		printf("请更新网络库\n");
		return -1;

	case WSAEPROCLIM:
		printf("请尝试关掉不必要的软件，以为当前网络运行提供充足的资源\n");
		return -1;

	case WSAEINPROGRESS:
		printf("请重新启动\n");
		return -1;
	}
#endif

	memset(&remote_addr, 0, sizeof(remote_addr));			   // 数据初始化--清零
	remote_addr.sin_family = AF_INET;						   // 设置为IP通信
	remote_addr.sin_addr.s_addr = inet_addr("82.156.237.194"); // 服务器IP地址
	//remote_addr.sin_addr.s_addr = inet_addr("127.0.0.1");	   // 服务器IP地址
	remote_addr.sin_port = htons(8000); // 服务器端口号

	memset(&my_addr, 0, sizeof(my_addr)); // 数据初始化--清零
	my_addr.sin_family = AF_INET;		  // 设置为IP通信
	my_addr.sin_addr.s_addr = INADDR_ANY; // 服务器IP地址--允许连接到所有本地地址上
	my_addr.sin_port = htons(8001);		  // 服务器端口号
										  /*创建客户端套接字--IPv4协议，面向无连接通信，UDP协议*/
	if ((client_sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
	{
		perror("socket");
		return 1;
	}
	/*将套接字绑定到服务器的网络地址上*/
	if (bind(client_sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) < 0)
	{
		perror("bind");
		return 1;
	}

	sin_size = sizeof(struct sockaddr_in);
	std::thread t(thread_task, client_sockfd);

	i = 0;
	while (1)
	{
		sprintf(buf, "This is a test message:%d", i++);

		/*向服务器发送数据包*/
		if ((len = sendto(client_sockfd, buf, strlen(buf), 0, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr))) < 0)
		{
			perror("sendto");
			return 1;
		}
		printf("sending: '%s', %d\n", buf, len);
#ifdef WIN32
		Sleep(2000);
	}
	closesocket(client_sockfd);
	WSACleanup();
#else
		usleep(2000000);
	}
	close(client_sockfd);
#endif

	return 0;
}
